namespace FFF.Test.Application.Repositories.Demo
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Abp.Domain.Repositories;
    using Abp.EntityFrameworkCore;
    using Abp.ObjectMapping;
    using Abp.UI;
    using Ydm.Helper;
    using Ydm.Extensions;
    using Microsoft.EntityFrameworkCore;
    using AutoMapper.QueryableExtensions;
    using FFF.Test.DataAccess.Framework;
    using FFF.Test.Application.Repositories.Demo;
    using FFF.Test.Entity.Demo;
    using FFF.Test.Entity.Demo.Dto;
    using FFF.Test.Entity.Demo.View;
    using Abp.Application.Services.Dto;

    /// <summary>
    /// 学生表仓储
    /// </summary>
    public class DemoStudent2Repository :
        YdmAbpRepositoryBase<DemoStudent2Entity, Guid, DemoStudent2CreateInputDto, DemoStudent2UpdateInputDto, DemoStudent2Dto, ViewDemoStudent2, ViewDemoStudent2>,
        IDemoStudent2Repository
    {
        private readonly IObjectMapper _objectMapper;

        /// <summary>
        /// Initializes a new instance of the <see cref="DemoStudent2Repository"/> class.
        /// 仓储构造方法
        /// </summary>
        /// <param name="dbContextProvider">对应数据库的对象</param>
        /// <param name="objectMapper">自动映射对象</param>
        public DemoStudent2Repository(
            IDbContextProvider<MyDbContext> dbContextProvider,
            IObjectMapper objectMapper
            )
            : base(dbContextProvider, objectMapper)
        {
            this._objectMapper = objectMapper;
        }

        /// <summary>
        /// 1._7_024批量同步(fff,商户平台)
        /// </summary>
        /// <param name="inDto">批量同步输入dto</param>
        /// <returns>批量同步输出dto</returns>
        public async Task<BatchSyncAsyncOutDto> BatchSyncAsyncAsync(BatchSyncAsyncInDto inDto)
        {
            var viewDemoStudent2Query = this.GetView();
            var result = new BatchSyncAsyncOutDto();
            result = await viewDemoStudent2Query.ProjectTo<BatchSyncAsyncOutDto>().FirstOrDefaultAsync();
            return result;
        }

        /// <summary>
        /// 判断添加时学生Id是否为1
        /// </summary>
        /// <param name="id">The identifier.</param>
        /// <returns>是否为1</returns>
        /// <remarks>ydm 2021-08-10</remarks>
        public async Task<bool> IsAddStudentIdAsync(string id)
        {
            return await Task.Run(() =>
            {
                return id == "1";
            });
        }

        /// <summary>
        /// 判断添加时学生的id是否为100
        /// </summary>
        /// <param name="id">The identifier.</param>
        /// <returns>是否为1</returns>
        /// <remarks>ydm 2021-08-10</remarks>
        public async Task<bool> IsEditStudentIdAsync(string id)
        {
            return await Task.Run(() =>
            {
                return id == "100";
            });
        }

        /// <summary>
        /// 是否存在输入学生姓名
        /// </summary>
        /// <param name="studentName">Name of the student.</param>
        /// <returns>是否为1</returns>
        /// <remarks>ydm 2021-08-10</remarks>
        public async Task<bool> IsExistStudentNameAsync(string studentName)
        {
            bool isExisits = await base.CountAsync(x => x.StudentName == studentName) > 0;
            return isExisits;
        }

        /// <summary>
        /// 判断学生等级是否为学霸
        /// </summary>
        /// <param name="demoStudent2StudentLevel">The demo student2 student level.</param>
        /// <returns>是否为1</returns>
        /// <remarks>ydm 2021-08-10</remarks>
        public async Task<bool> IsStraightAsync(DemoStudent2StudentLevelEnum demoStudent2StudentLevel)
        {
            return await Task.Run(() =>
            {
                return demoStudent2StudentLevel.ToString() == "1";
            });
        }

        /// <summary>
        /// create by dto as an asynchronous operation.
        /// </summary>
        /// <param name="inputDto">The input dto.</param>
        /// <returns>Task&lt;DemoStudent2Dto&gt;.</returns>
        /// <exception cref="UserFriendlyException">
        /// 学生姓名已存在
        /// or
        /// 学生id必须为1
        /// </exception>
        /// <remarks>ydm 2021-08-10</remarks>
        public override async Task<DemoStudent2Dto> CreateByDtoAsync(DemoStudent2CreateInputDto inputDto)
        {
            //if (await this.IsExistStudentNameAsync(inputDto.StudentName))
            //{
            //    throw new UserFriendlyException("学生姓名已存在");
            //}

            //if (!await this.IsAddStudentIdAsyns(inputDto.Id.ToString()))
            //{
            //    throw new UserFriendlyException("学生id必须为1");
            //}

            return await base.CreateByDtoAsync(inputDto);
        }

        /// <summary>
        /// update by dto as an asynchronous operation.
        /// </summary>
        /// <param name="inputDto">The input dto.</param>
        /// <returns>Task&lt;DemoStudent2Dto&gt;.</returns>
        /// <exception cref="UserFriendlyException">学生id不能为100</exception>
        /// <remarks>ydm 2021-08-10</remarks>
        public override async Task<DemoStudent2Dto> UpdateByDtoAsync(DemoStudent2UpdateInputDto inputDto)
        {
            if (await this.IsEditStudentIdAsync(inputDto.Id.ToString()))
            {
                throw new UserFriendlyException("学生id不能为100");
            }

            // 批量更新
            int upateResult = await this.GetAll()
                .Where(x => x.StudentAge > 16)
                .UpdateFromQueryAsync(x => new DemoStudent2Entity { StudentAge = 18, StudentIsVip = 1 });

            // 查询
            var insertResult = await this.GetView()
                .Where(x => x.StudentAge > 1)
                .ProjectTo<DemoStudent2Dto>()
                .ToListAsync();

            //批量同步
            await this.GetAll()
               .Where(x => x.StudentIsVip == 1)
               .ToListAsync();
            return await base.UpdateByDtoAsync(inputDto);
        }

        /// <summary>
        /// 进行分组查询
        /// </summary>
        /// <param name="inDto">The indto.</param>
        /// <returns> 分页对象</returns>
        /// <remarks>ydm 2021-08-12</remarks>
        public async Task<List<GetStuGroupGradeOutDto>> GetStuDtoGroupByGradeAsync(GetStuGroupGradeInDto inDto)
        {
            var stuList = await this.GetView()
                .Where(x => x.IsMan == inDto.IsMan)
                .GroupBy(
                 x => new { x.IsMan, x.StudentLevel },
                (key, list) => new GetStuGroupGradeOutDto { IsMan = key.IsMan, StudentLevel = (DemoStudent2StudentLevelEnum)key.StudentLevel, Count = list.Count() })
                .ToListAsync();
            return stuList;
        }

        /// <summary>
        /// 根据年龄和性别进行查询
        /// </summary>
        /// <param name="inDto">The indto.</param>
        /// <returns>学生dto</returns>
        /// <remarks>ydm 2021-08-12</remarks>
        public async Task<GetStuDtoByAgeAndSexOutDto> GetStuDtoByAgeAndSexAsync(GetStuDtoByAgeAndSexInDto inDto)
        {
            //var stuList = await this.GetView()
            //   .Where(x => x.StudentAge == inDto.StudentAge)
            //   .Where(x => x.IsMan == inDto.IsMan)
            //   .ProjectTo<DemoStudent2Dto>()
            //   .ToListAsync();

            //return new GetStuDtoByAgeAndSexOutDto() { StudentDtos = stuList };

            PagedInputDto pageInPut = new PagedInputDto()
            {
                PageIndex = 2,
                PageSize = 2,
                Order = "StudentAge desc"
            };

            var pageStudets = await this.GetView()
                   .Where(x => x.IsMan == inDto.IsMan && x.StudentAge == inDto.StudentAge)
                   .GetPageAsync<ViewDemoStudent2, DemoStudent2Dto>(pageInPut);

            return new GetStuDtoByAgeAndSexOutDto() { StudentDtos = pageStudets.DataList };

        }

        /// <summary>
        /// 批量更新
        /// </summary>
        /// <param name="studentAge">学生年龄</param>
        /// <returns>int</returns>
        /// <remarks>ydm 2021-08-12</remarks>
        public async Task<bool> BatchUpdateAsync(int studentAge)
        {
            int upateResult = await this.GetAll()
                .Where(x => x.StudentAge > 1)
                .UpdateFromQueryAsync(x => new DemoStudent2Entity { StudentAge = studentAge });

            //this.dbContextProvider.GetDbContext().BulkSaveChanges();
            if (upateResult > 0)
            {
                return true;
            }
            else
            {
                throw new UserFriendlyException("更新失败");
            }
        }

        /// <summary>
        /// 批量插入
        /// </summary>
        /// <param name="student2Entitys">The indto.</param>
        /// <returns>是否成功</returns>
        /// <remarks>ydm 2021-08-12</remarks>
        public async Task<bool> BatchInsertAsync(List<DemoStudent2Entity> student2Entitys)
        {
            try
            {
                await this.GetDbContextMy().BulkInsertAsync(student2Entitys);
                return true;
            }
            catch (Exception ex)
            {
                throw new UserFriendlyException("插入失败");

            }

        }

    }
}
